package com.cskaoyan.order.service.impl;

import com.cskaoyan.mall.commons.constant.SysRetCodeConstants;
import com.cskaoyan.mall.commons.exception.BizException;
import com.cskaoyan.mall.commons.exception.ExceptionProcessorUtils;
import com.cskaoyan.mall.order.constant.OrderRetCode;
import com.cskaoyan.order.biz.TransOutboundInvoker;
import com.cskaoyan.order.biz.context.AbsTransHandlerContext;
import com.cskaoyan.order.biz.factory.OrderProcessPipelineFactory;
import com.cskaoyan.order.constant.OrderConstants;
import com.cskaoyan.order.dal.entitys.Order;
import com.cskaoyan.order.dal.entitys.OrderItem;
import com.cskaoyan.order.dal.entitys.Stock;
import com.cskaoyan.order.dal.persistence.OrderItemMapper;
import com.cskaoyan.order.dal.persistence.OrderMapper;
import com.cskaoyan.order.dal.persistence.OrderShippingMapper;
import com.cskaoyan.order.dal.persistence.StockMapper;
import com.cskaoyan.order.dto.*;
import com.cskaoyan.order.service.OrderCoreService;
import com.cskaoyan.order.utils.GlobalIdGeneratorUtil;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RMap;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Example;

import java.util.List;

@Slf4j
@Service
public class OrderCoreServiceImpl implements OrderCoreService {


    @Autowired
    OrderMapper orderMapper;

    @Autowired
    OrderItemMapper orderItemMapper;

    @Autowired
    OrderShippingMapper orderShippingMapper;

    @Autowired
    OrderProcessPipelineFactory orderProcessPipelineFactory;

    @Autowired
    StockMapper stockMapper;

    @Autowired
    RedissonClient redissonClient;


    /**
     * 创建订单的处理流程
     *
     * @param request
     * @return
     */
    @Override
    public CreateOrderResponse createOrder(CreateOrderRequest request) {
        CreateOrderResponse response = new CreateOrderResponse();
        try {
            //创建pipeline对象
            TransOutboundInvoker invoker = orderProcessPipelineFactory.build(request);

            //启动pipeline
            invoker.start(); //启动流程（pipeline来处理）

            //获取处理结果
            AbsTransHandlerContext context = invoker.getContext();

            //把处理结果转换为response
            response = (CreateOrderResponse) context.getConvert().convertCtx2Respond(context);

            RMap<Object, Object> orderErrorMap = redissonClient.getMap("orderErrorMap");
            if (orderErrorMap != null && orderErrorMap.get(request.getUserId()) != null) {
                String errorCode = orderErrorMap.remove(request.getUserId()).toString();
                response.setCode(errorCode);
                response.setMsg(SysRetCodeConstants.getMessage(errorCode));
                return response;
            }

            response.setCode(SysRetCodeConstants.SUCCESS.getCode());
            response.setMsg(SysRetCodeConstants.SUCCESS.getMessage());


        } catch (Exception e) {
            log.error("OrderCoreServiceImpl.createOrder Occur Exception :" + e);
            ExceptionProcessorUtils.wrapperHandlerException(response, e);
        }
        return response;
    }

    /**
     * 取消订单
     *
     * @param request
     * @return
     */
    @Override
    public CancelOrderResponse cancelOrder(CancelOrderRequest request) {
        CancelOrderResponse cancelOrderResponse = new CancelOrderResponse();
        //取消订单,status -> 7.冻结库存回退
        String orderId = request.getOrderId();

        Order order = new Order();
        order.setStatus(OrderConstants.ORDER_STATUS_TRANSACTION_CANCEL);
        order.setOrderId(orderId);

        int i = orderMapper.updateByPrimaryKeySelective(order);
        if (i < 1) {
            //失败
            throw new BizException(OrderRetCode.DB_EXCEPTION.getCode());
        }
        Example example = new Example(OrderItem.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("orderId", orderId);
        List<OrderItem> orderItems = orderItemMapper.selectByExample(example);
        for (OrderItem orderItem : orderItems) {
            Stock stock = new Stock();

            Long itemId = orderItem.getItemId();
            Integer num = orderItem.getNum();
            stock.setItemId(itemId);
            stock.setStockCount(num.longValue());
            stock.setLockCount(-num);
            stockMapper.updateStock(stock);
        }
        cancelOrderResponse.setCode(OrderRetCode.SUCCESS.getCode());
        cancelOrderResponse.setMsg(OrderRetCode.SUCCESS.getMessage());
        return cancelOrderResponse;
    }

    /**
     * 删除订单
     *
     * @param request
     * @return
     */
    @Override
    public DeleteOrderResponse deleteOrder(DeleteOrderRequest request) {
        DeleteOrderResponse deleteOrderResponse = new DeleteOrderResponse();
        String orderId = request.getOrderId();
        Example example = new Example(Order.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("orderId", orderId);
        Order order = orderMapper.selectByOrderId(orderId);
        Integer status = order.getStatus();
        if (status == OrderConstants.ORDER_STATUS_PAYED || status == OrderConstants.ORDER_STATUS_READY_TRANSACTION || status == OrderConstants.ORDER_STATUS_TRANS) {
            //个别状态订单不允许删除
            deleteOrderResponse.setCode(OrderRetCode.ORDER_DEL_ERROR.getCode());
            deleteOrderResponse.setMsg(OrderRetCode.ORDER_DEL_ERROR.getMessage());
            return deleteOrderResponse;
        } else {
            if (status == OrderConstants.ORDER_STATUS_INIT) {
                //未付款删除,冻结库存回退
                Example example1 = new Example(OrderItem.class);
                Example.Criteria criteria1 = example1.createCriteria();
                criteria1.andEqualTo("orderId", orderId);
                List<OrderItem> orderItems = orderItemMapper.selectByExample(example1);
                for (OrderItem orderItem : orderItems) {
                    Stock stock = new Stock();

                    Long itemId = orderItem.getItemId();
                    Integer num = orderItem.getNum();
                    stock.setItemId(itemId);
                    stock.setStockCount(num.longValue());
                    stock.setLockCount(-num);
                    stockMapper.updateStock(stock);
                }
            }
            orderMapper.deleteByExample(example);
            orderItemMapper.deleteByExample(example);
            orderShippingMapper.deleteByExample(example);
        }

        deleteOrderResponse.setCode(OrderRetCode.SUCCESS.getCode());
        deleteOrderResponse.setMsg(OrderRetCode.SUCCESS.getMessage());
        return deleteOrderResponse;
    }

}
